//
//  SWBookAssetManager.swift
//  YiyaPuzzleDemo
//
//  Created by linhan on 16/9/29.
//  Copyright © 2016年 test. All rights reserved.
//

import Foundation

enum SWPhotoSizeLevel:String
{
    //原图
    case origin
    //处理过的
    case processed
    //预览
    case preview
    //缩略图
    case thumbnail
}

private let _manager:SWBookAssetManager = SWBookAssetManager()
class SWBookAssetManager: NSObject
{
    private var _bookID:String = "default"
    
//    private var _dataPath:String{
//        return (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).valueAt(0) ?? "") + "/bookassets.data"
//    }
    
    private var _dataPath:String = ""
    
    var cacheDirectory:String = ""
    private var _fileManager = FileManager.default
    private var _launch:Bool = false
    private var _records:[SWBookAssetRecord] = []
    
    let ioQueue = DispatchQueue(label: "SWBookAssetManager.ioQueue", attributes: .concurrent)
    let processQueue = DispatchQueue(label: "SWBookAssetManager.processQueue", attributes: .concurrent)
    
    class func sharedManager() -> SWBookAssetManager
    {
        return _manager
    }
    
    override init() {
        
    }
    
    func launch()
    {
        if !_launch
        {
            _launch = true
            
            // document/book/bookID.data
            // document/book/imageID_preview
            // document/book/imageID_processed
            // document/book/imageID_origin
            
            _dataPath = "\(SWBookManager.sharedManager().baseDirectory)/bookassets.data"
            _records = SWCacheManager.sharedManager().readCache(_dataPath) as? [SWBookAssetRecord] ?? []
            
        }
    }
    
//    func setBook(_ bookID:String)
//    {
//        _bookID = bookID ??? _bookID
//        cacheDirectory = "\(basePath)/\(_bookID)"
//        if !_fileManager.fileExists(atPath: cacheDirectory)
//        {
//            try? _fileManager.createDirectory(atPath: cacheDirectory, withIntermediateDirectories: true, attributes: nil)
//        }
//    }
    
    func addPhotoToBook(_ image:UIImage, data:Data, page:SWPage)
    {
        //page.bookID
    }
    
    //添加照片(原图)
    func addPhoto(_ image:UIImage, data:Data) -> String
    {
        let imageID:String = StringUtil.getUniqid(5)
        ioQueue.async(flags: .barrier) {
            
            //存储原图
            let originPath:String = self.getPhotoPath(imageID, level: .origin)
            FileUtility.saveImageCacheToPath(originPath, image:data)
            
            //存储处理图(裁剪成正方形)
            let processedImage:UIImage = self.resizeImageForProcessible(image)
            print("processedImage:", processedImage.size, processedImage.scale)
            if let processedData = UIImageJPEGRepresentation(processedImage, 0.9)
            {
                let path = self.getPhotoPath(imageID, level: .processed)
                FileUtility.saveImageCacheToPath(path, image:processedData)
            }
            
            //存储预览图
            let previewImage = Toucan.Resize.resizeImage(image, size: SW.Config.PreviewImageOriginSize.divide(image.scale), fitMode:.crop)
            if let processedData = UIImageJPEGRepresentation(previewImage, 0.9)
            {
                let path = self.getPhotoPath(imageID, level: .preview)
                FileUtility.saveImageCacheToPath(path, image:processedData)
            }
            
            //缩略图
            let thumbnailImage = Toucan.Resize.resizeImage(previewImage, size: SW.Config.ThumbnailImageOriginSize.divide(previewImage.scale), fitMode:.crop)
            if let processedData = UIImageJPEGRepresentation(thumbnailImage, 0.9)
            {
                let path = self.getPhotoPath(imageID, level: .thumbnail)
                FileUtility.saveImageCacheToPath(path, image:processedData)
            }
            
            
            
            if !self._records.contains(where: {($0.imageID ?? "") == imageID})
            {
                let record:SWBookAssetRecord = SWBookAssetRecord()
                record.imageID = imageID
                self._records.append(record)
                self.save()
            }
            
        }
        
        return imageID
    }
    
    //替换图片
    func replacePhoto(_ imageID:String, processedImage:UIImage, originImage:UIImage, originData:Data?, completion:@escaping (()->Void))
    {
        ioQueue.async(flags: .barrier) {
            //存储原图
            if let data = originData
            {
                self.savePhoto(data, imageID: imageID, level: .origin)
            }
            else
            {
                self.savePhoto(originImage, imageID: imageID, level: .origin)
            }
            
            self.updatePhoto(processedImage, imageID: imageID, completion: completion)
        }
    }
    
    //对应图片是否存在
    func photoExists(_ imageID:String, level:SWPhotoSizeLevel) -> Bool
    {
        let path:String = getPhotoPath(imageID, level: level)
        return _fileManager.fileExists(atPath: path)
    }
    
    //通过图片ID获取图片(默认获取单倍率图片)
    func getImage(_ imageID:String, level:SWPhotoSizeLevel, scale:CGFloat = 1) -> UIImage?
    {
        let path:String = getPhotoPath(imageID, level: level)
        return FileUtility.imageDataFromPath(path, scale: scale)
    }
    
    func getImage(_ imageID:String, level:SWPhotoSizeLevel, completion:@escaping ((UIImage?)->Void))
    {
        let path:String = getPhotoPath(imageID, level: level)
        ioQueue.async {
            let image:UIImage? = FileUtility.imageDataFromPath(path, scale: 1)
            completion(image)
        }
    }
    
    //图片是否修改过
    func imageModified(_ imageID:String) -> Bool
    {
        var modified:Bool = false
        if let index = self._records.index(where: {($0.imageID ?? "") == imageID}),
           let record = self._records.valueAt(index)
        {
            modified = record.modified 
        }
        return modified
    }
    
    //修改更新照片
    func updatePhoto(_ image:UIImage, imageID:String, completion:@escaping (()->Void))
    {
        ioQueue.async(flags: .barrier) {
            
            let processedImage:UIImage = self.resizeImageForProcessible(image)
            self.savePhoto(processedImage, imageID: imageID, level: .processed)
            trace("updatePhoto:", processedImage.scale, processedImage.size)
            
            //在编辑器中对照片进行变更处理后，考虑图片到编辑器处理步骤无法重现，因此删除原图，保留处理后的图片，做为之后再处理使用
            /**
            let originPath:String = self.getPhotoPath(imageID, level: .origin)
            if self._fileManager.fileExistsAtPath(originPath)
            {
                try? self._fileManager.removeItemAtPath(originPath)
            }**/
            
            //存储预览图
            let previewImage = Toucan.Resize.resizeImage(image, size: SW.Config.PreviewImageOriginSize.divide(image.scale), fitMode:.crop)
            self.savePhoto(previewImage, imageID: imageID, level: .preview)
            
            let thumbnailImage = Toucan.Resize.resizeImage(previewImage, size: SW.Config.ThumbnailImageOriginSize.divide(previewImage.scale), fitMode:.crop)
            self.savePhoto(thumbnailImage, imageID: imageID, level: .thumbnail)
            
            
            //记录更新记录
            if let index = self._records.index(where: {($0.imageID ?? "") == imageID}),
               let record = self._records.valueAt(index)
            {
                record.modified = true
                self.save()
            }
            
            completion()
            
            SWNotificationCenter.post(name: NotificationName.BookPagePhotoUpdated, object: nil, userInfo: [SWKey.imageID:imageID])
        }
    }
    
    //保存图片到对应的规格
    func savePhoto(_ image:UIImage, imageID:String, level:SWPhotoSizeLevel)
    {
        if let data = UIImageJPEGRepresentation(image, 0.9)
        {
            self.savePhoto(data, imageID: imageID, level: level)
        }
    }
    
    //保存图片
    func savePhoto(_ data:Data, imageID:String, level:SWPhotoSizeLevel)
    {
        let path = self.getPhotoPath(imageID, level: level)
        FileUtility.saveImageCacheToPath(path, image:data)
    }
    
    //移除图片
    func removePhoto(_ imageID:String)
    {
        var paths:[String] = []
        paths.append(getPhotoPath(imageID, level: .origin))
        paths.append(getPhotoPath(imageID, level: .processed))
        paths.append(getPhotoPath(imageID, level: .preview))
        for path in paths
        {
            if _fileManager.fileExists(atPath: path)
            {
                try? _fileManager.removeItem(atPath: path)
            }
        }
    }
    
//    private func getValidBookID(bookID:String?) -> String
//    {
//        let id:String? = bookID ??? SWBookManager.sharedManager().book?.bookID
//        return (id ??? "")
//    }
    
    //通过图片ID和图片等级获取图片路径
    private func getPhotoPath(_ imageID:String, level:SWPhotoSizeLevel) -> String
    {
        //let aBookID:String = getValidBookID(bookID:bookID)
        let path:String = "\(SWBookManager.sharedManager().baseDirectory)/\(imageID)_\(level.rawValue).jpg"
        return path
    }
    
    //处理成合规的适合处理的尺寸
    private func resizeImageForProcessible(_ image:UIImage) -> UIImage
    {
        var processedImage:UIImage
        if image.originSize.minEdge < SW.Config.ProcessImagePresetOriginSize.minEdge
        {
            //没超过指定尺寸的，按照原图片最短边正方形裁切
            let minEdge = image.size.minEdge
            let cropRect:CGRect = CGRectMake(floor((image.size.width - minEdge) * 0.5), floor((image.size.height - minEdge) * 0.5), minEdge, minEdge)
            processedImage = Toucan.Util.croppedImageWithRect(image, rect: cropRect)
        }
        else
        {
            //大于指定尺寸的, 按指定尺寸正方形裁切
            let size = SW.Config.ProcessImagePresetOriginSize.divide(image.scale)
            processedImage = Toucan.Resize.resizeImage(image, size: size, fitMode:.crop)
        }
        return processedImage
    }
    
    private func save()
    {
        SWCacheManager.sharedManager().writeCache(_records, path: _dataPath)
    }
    
}
